#include "CVtkImageCmp.h"


#include <vtkSmartPointer.h>
#include <vtkParametricFunctionSource.h>
#include <vtkParametricSpline.h>
#include <vtkCellArray.h>
#include <vtkDoubleArray.h>
#include <vtkCellData.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkGlyph3DMapper.h>
#include <vtkSphereSource.h>
#include <vtkNamedColors.h>
#include <vtkAutoInit.h>
#include <vtkInteractorStyleTrackballCamera.h>

VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);


std::vector<CVtkImageCmp::coord3d> CVtkImageCmp::analysis(const QString &path, QStringList filters)
{
    qDebug()<<QFileInfo(path).absolutePath();
    QFileInfoList infos= QDir(QFileInfo(path).absolutePath()).entryInfoList();
    QFileInfoList valids;
    for(QFileInfo info:infos)
    {
        if(info.fileName()=="."||info.fileName()=="..")continue;
        if(!filters.contains(info.suffix().toLower()))
        {
            qDebug()<<"filter"<<info.suffix().toLower();
            continue;
        }
        valids.push_back(info);
    }
    infos.clear();
    std::vector<coord3d> coords;
    for(int i=0;i<valids.size()-2;i++)
    {
        QFileInfo info0=valids[i];
        QString file0=info0.filePath();
        QImage image0(file0);

        QFileInfo info1=valids[i+1];
        QFileInfo info2=valids[i+2];

        QString file1=info1.filePath();
        QString file2=info2.filePath();
        QImage image1(file1);
        QImage image2(file2);

        for(int x=0;x<image0.width();x++)
        {
            for(int y=0;y<image0.height();y++)
            {
                QRgb r0=image0.pixel(x,y);
                QRgb r1=image1.pixel(x,y);
                //QRgb r2=image2.pixel(x,y);
                if(r0==r1)continue;

                if(qRed(r0)>0)
                {
                    coord3d coord;
                    coord.x=x;
                    coord.y=y;
                    coord.z=i;
                    coords.push_back(coord);
                }
            }
        }
        qDebug()<<file0;
    }
    qDebug()<<coords.size();
    return coords;
}

vtkSmartPointer<vtkMapper>CVtkImageCmp::mapper(std::vector<CVtkImageCmp::coord3d> coords)
{
    vtkSmartPointer<vtkPoints> points = vtkPoints::New();
    for (unsigned i = 0; i < coords.size(); ++i)
    {
        coord3d c=coords[i];
        points->InsertNextPoint(c.x,c.y,c.z);
    }

    vtkSmartPointer<vtkSphereSource> sphere=
            vtkSmartPointer<vtkSphereSource>::New();
    sphere->SetPhiResolution(10);
    sphere->SetThetaResolution(10);
    sphere->SetRadius(0.5f);

    vtkSmartPointer<vtkPolyData> pd= vtkPolyData::New();
    pd->SetPoints(points);

    vtkSmartPointer<vtkGlyph3DMapper> pointMapper=
            vtkSmartPointer<vtkGlyph3DMapper>::New();
    pointMapper->SetInputData(pd);
    pointMapper->SetSourceConnection(sphere->GetOutputPort());
    return pointMapper;
}

void CVtkImageCmp::cmp(QString path, QStringList fileters)
{
    qDebug()<<QFileInfo(path).absolutePath();
    QFileInfoList infos= QDir(QFileInfo(path).absolutePath()).entryInfoList();
    QFileInfoList valids;
    for(QFileInfo info:infos)
    {
        if(info.fileName()=="."||info.fileName()=="..")continue;
        if(!fileters.contains(info.suffix().toLower()))
        {
            qDebug()<<"filter"<<info.suffix().toLower();
            continue;
        }
        valids.push_back(info);
    }
    infos.clear();
    std::vector<coord3d> coords;
    for(int i=0;i<valids.size()-2;i++)
    {
        QFileInfo info0=valids[i];
        QString file0=info0.filePath();
        QImage image0(file0);

        QFileInfo info1=valids[i+1];
        QFileInfo info2=valids[i+2];

        QString file1=info1.filePath();
        QString file2=info2.filePath();
        QImage image1(file1);
        QImage image2(file2);

        for(int x=0;x<image0.width();x++)
        {
            for(int y=0;y<image0.height();y++)
            {
                QRgb r0=image0.pixel(x,y);
                QRgb r1=image1.pixel(x,y);
                //QRgb r2=image2.pixel(x,y);
                if(r0==r1)continue;

                if(qRed(r0)>0)
                {
                    coord3d coord;
                    coord.x=x;
                    coord.y=y;
                    coord.z=i;
                    coords.push_back(coord);
                }
            }
        }
        qDebug()<<file0;
    }
    qDebug()<<coords.size();
    showCmp(2,4,coords);
}

void CVtkImageCmp::showCmp(float gaps, float pixelSize, std::vector<CVtkImageCmp::coord3d> coords)
{
    vtkSmartPointer<vtkPoints> points = vtkPoints::New();
    for (unsigned i = 0; i < coords.size(); ++i)
    {
        coord3d c=coords[i];
        points->InsertNextPoint(c.x,c.y,c.z);
    }

    vtkSmartPointer<vtkSphereSource> sphere=
            vtkSmartPointer<vtkSphereSource>::New();
    sphere->SetPhiResolution(10);
    sphere->SetThetaResolution(10);
    sphere->SetRadius(0.5f);

    vtkSmartPointer<vtkPolyData> pd= vtkPolyData::New();
    pd->SetPoints(points);

    vtkSmartPointer<vtkGlyph3DMapper> pointMapper=
            vtkSmartPointer<vtkGlyph3DMapper>::New();
    pointMapper->SetInputData(pd);
    pointMapper->SetSourceConnection(sphere->GetOutputPort());

    vtkSmartPointer<vtkActor> actor=vtkActor::New();
    actor->SetMapper(pointMapper);

    double pointActorColor[]={0,5,0.2,0.3};
    actor->GetProperty()->SetColor(pointActorColor);


    vtkSmartPointer<vtkRenderer> renderer=vtkRenderer::New();
    renderer->AddActor(actor);
//    renderer->SetBackground(1,1,1);
    vtkSmartPointer<vtkRenderWindow> renderWindow=vtkRenderWindow::New();
    renderWindow->AddRenderer(renderer);

    vtkSmartPointer<vtkRenderWindowInteractor> rwi=vtkRenderWindowInteractor::New();

    vtkSmartPointer<vtkInteractorStyleTrackballCamera> style=vtkInteractorStyleTrackballCamera::New();

    rwi->SetRenderWindow(renderWindow);
    rwi->SetInteractorStyle(style);
    renderWindow->Render();
    rwi->Start();
}
